// 1.3.7 指针-其他概念-C++ 从函数返回指针

/**
 * 
 * 学习 C++ 的指针既简单又有趣。通过指针，可以简化一些 C++ 编程任务的执行，还有一些任务，如动态内存分配，没有指针是无法执行的。所以，想要成为一名优秀的 C++ 程序员，学习指针是很有必要的。
 * 正如您所知道的，每一个变量都有一个内存位置，每一个内存位置都定义了可使用连字号（&）运算符访问的地址，它表示了在内存中的一个地址。请看下面的实例，它将输出定义的变量地址：
 * 
 * ------------------
 * 其他概念
 * 在 C++ 中，有很多指针相关的概念，这些概念都很简单，但是都很重要。下面列出了 C++ 程序员必须清楚的一些与指针相关的重要概念：
 * 
 * 1. C++ Null 指针
 * C++ 支持空指针。NULL 指针是一个定义在标准库中的值为零的常量。
 * 
 * 2. C++ 指针的算术运算
 * 可以对指针进行四种算术运算：++、--、+、-
 * 
 * 3. C++ 指针 vs 数组
 * 指针和数组之间有着密切的关系。
 * 
 * 4. C++ 指针数组
 * 可以定义用来存储指针的数组。
 * 
 * 5. C++ 指向指针的指针
 * C++ 允许指向指针的指针。
 * 
 * 6. C++ 传递指针给函数
 * 通过引用或地址传递参数，使传递的参数在调用函数中被改变。
 * 
 * 7. C++ 从函数返回指针
 * C++ 允许函数返回指针到局部变量、静态变量和动态内存分配。
 * 
 * ~~~~~~~~~~~~~~~~~~~~
 * C++ 从函数返回指针
 * 在上一章中，我们已经了解了 C++ 中如何从函数返回数组，类似地，C++ 允许您从函数返回指针。为了做到这点，您必须声明一个返回指针的函数，如下所示：
    int * myFunction()
    {
    .
    .
    .
    }
 * 另外，C++ 不支持在函数外返回局部变量的地址，除非定义局部变量为 static变量。
 * 现在，让我们来看下面的函数，它会生成 10 个随机数，并使用表示指针的数组名（即第一个数组元素的地址）来返回它们，具体如下（示例一）：
 *
*/

#include <iostream>
#include <ctime>
int *getRandNums(const int n = 10);

int main(void)
{
  /**
   * 示例一
  */
  int *p = getRandNums();
  for (int i = 0; i < 10; i++)
  {
    std::cout << i + 1 << " : " << p[i] << std::endl;
    // std::cout << i + 1 << " : " << *(p + i) << std::endl;
  }

  int test[] = {1, 2, 3};
  int *ptr;
  ptr = &test[0];
  for (int i = 0; i < 3; i++)
  {
    std::cout << i + 1 << " : " << ptr[i] << std::endl;
    std::cout << i + 1 << " : " << (&test[0])[i] << std::endl;
    // [i]这个好像等价于 +i
    std::cout << i + 1 << " : " << (&test[1])[i] << std::endl;
    std::cout << "-----" << std::endl;
  }

  printf("-------------end--------------\n");
  return 0;
}

int *getRandNums(const int n)
{
  std::cout << "n : " << n << std::endl;
  srand((unsigned)time(NULL));
  // int arr[n]; // 程序中断
  // static int arr[n]; // error: storage size of 'arr' isn't constant
  static int arr[10];
  for (int i = 0; i < n; i++)
  {
    arr[i] = rand();
  }

  // return arr;
  return &arr[0];
}
